// Copyright 2005 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package org.apache.tapestry5.internal.portlet.services;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import javax.portlet.PortletRequest;
import javax.portlet.PortletSession;

import org.apache.tapestry5.ioc.internal.util.InternalUtils;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.Session;
import org.apache.tapestry5.services.SessionPersistedObjectAnalyzer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Implementation of {@link org.apache.tapestry.web.WebRequest} that adapts a
 * {@link PortletRequestImpl} .
 * 
 * @author Howard M. Lewis Ship
 * @since 4.0
 */
public class PortletRequestImpl implements Request {

    private static final String            REQUESTED_WITH_HEADER = "X-Requested-With";

    private static final String            XML_HTTP_REQUEST      = "XMLHttpRequest";

    private final Logger                   _logger               = LoggerFactory.getLogger(PortletRequestImpl.class);

    private final PortletRequest           _request;

    private final String                   _pageName;

    private Session                        _session;

    private SessionPersistedObjectAnalyzer _analyzer;

    public PortletRequestImpl(PortletRequest request, String pageName, SessionPersistedObjectAnalyzer analyzer) {
        this._request = request;
        this._pageName = pageName;
        this._analyzer = analyzer;
    }

    @Override
    public Session getSession(boolean create) {
        if (this._session != null) {
            return this._session;
        }

        PortletSession session = this._request.getPortletSession(create);

        if (session != null) {
            this._session = new PortletSessionImpl(session, this._analyzer);
        }

        return this._session;
    }

    @Override
    public String getContextPath() {
        return this._request.getContextPath();
    }

    @Override
    public List<String> getParameterNames() {
        return InternalUtils.toList(this._request.getParameterNames());
    }

    @Override
    public String getParameter(String name) {
        return this._request.getParameter(name);
    }

    @Override
    public String[] getParameters(String name) {
        //        Enumeration enumeration = _request.getParameterNames();
        //        while (enumeration.hasMoreElements()) {
        //            String parameter = (String) enumeration.nextElement();
        //            System.out.println("request parameter: " + parameter + " " + _request.getParameter(parameter));
        //        }
        return this._request.getParameterValues(name);
    }

    @Override
    public String getPath() {

        if (this._pageName == null) {
            // TODO: return portlet-page from PortletConfigProvider
            return "/";
        }

        return this._pageName.length() == 0 ? "/" : this._pageName;
    }

    @Override
    public Locale getLocale() {
        return this._request.getLocale();
    }

    @Override
    public List<String> getHeaderNames() {
        this._logger.error(PortletServicesMessages.unsupportedMethod("getHeaderNames"));

        return new ArrayList<String>();
    }

    @Override
    public long getDateHeader(String name) {
        this._logger.error(PortletServicesMessages.unsupportedMethod("getDateHeader"));

        return -1;
    }

    @Override
    public String getHeader(String name) {
        this._logger.error(PortletServicesMessages.unsupportedMethod("getHeader"));

        return null;
    }

    public void setEncoding(String requestEncoding) {
        this._logger.error(PortletServicesMessages.unsupportedMethod("setEncoding"));
    }

    @Override
    public boolean isXHR() {
        //    	_logger.info("Content-Type:" + _request.getResponseContentType());
        //    	
        //    	Enumeration<String> values = _request.getResponseContentTypes();
        //    	while (values.hasMoreElements()){
        //    		_logger.info(values.nextElement());
        //    	}
        //    	_logger.info("PORTLET CLASS:" + _request.getClass());
        //    	_logger.error(PortletServicesMessages.unsupportedMethod("isXHR"));

        //    	return false;

        String ajaxRequest = this._request.getParameter("AJAX_REQUEST");

        return "true".equalsIgnoreCase(ajaxRequest);

        //        LiferayPortletRequest liferayRequest = (LiferayPortletRequest) this._request;
        //        //    	Enumeration<String> values = liferayRequest.getHttpServletRequest().getHeaderNames();
        //        //    	
        //        //    	while (values.hasMoreElements()){
        //        //    		System.out.println(liferayRequest.getHttpServletRequest().getHeader(values.nextElement()));
        //        //    	}
        //
        //        HttpServletRequest httpServletRequest = liferayRequest.getHttpServletRequest();
        //
        //        for (Enumeration<?> header = httpServletRequest.getHeaderNames(); header.hasMoreElements();) {
        //            String name = (String) header.nextElement();
        //            Object value = httpServletRequest.getAttribute(name);
        //            this._logger.info("request header: {} - {}", name, value);
        //        }
        //
        //        if (PortletRequestImpl.XML_HTTP_REQUEST.equals(httpServletRequest
        //            .getHeader(PortletRequestImpl.REQUESTED_WITH_HEADER))) {
        //            this._logger.info("REQUEST IS XHR");
        //            return true;
        //        }
        //        else {
        //            return false;
        //        }
    }

    @Override
    public boolean isSecure() {
        return this._request.isSecure();
    }

    @Override
    public boolean isRequestedSessionIdValid() {
        return this._request.isRequestedSessionIdValid();
    }

    @Override
    public Object getAttribute(String name) {
        return this._request.getAttribute(name);
    }

    @Override
    public void setAttribute(String name, Object value) {
        this._request.setAttribute(name, value);
    }

    @Override
    public String getServerName() {
        return this._request.getServerName();
    }

    @Override
    public String getMethod() {
        //_logger.error(PortletServicesMessages.unsupportedMethod("getMethod"));

        return "POST";
    }

    @Override
    public int getLocalPort() {
        // TODO: not sure what should be returned here...
        throw new UnsupportedOperationException();
    }

    @Override
    public int getServerPort() {
        return this._request.getServerPort();
    }

}
